Ext.data.ProxyMgr.registerType('app.db.CheckListDB', Ext.extend(Ext.data.LocalStorageProxy, {

	
	constructor: function(config) {
		
		
		this.db = openDatabase('mychecklist', '1.0', 'mychecklist', 65536);
		
	
		
		
			this.db.transaction(
				function (transaction) {
					
					transaction.executeSql(
						'create table if not exists check_list (' +
						'id text not null primary key, ' +
						'listName text not null, ' +
						'listType text not null, ' +
						'createDate date not null default (datetime(current_timestamp)), ' +
						'status text not null default "active")'
					);
					
					transaction.executeSql(
						'create table if not exists list_items (' + 
						'id integer not null primary key autoincrement, ' +
						'itemOrder integer not null, ' +
						'listId text not null, ' +
						'item text not null, ' +
						'status text not null default "new")'
						
					);
					
				}
			);
				
		

        config = config || {};
		
		// this.superclass.constructor.call(this, config);
        
	
        if (config.model == undefined) {
            delete config.model;
        }
				
        Ext.data.Proxy.superclass.constructor.call(this, config);

        
	        if (this.model != undefined && !(this.model instanceof Ext.data.Model)) {
            this.setModel(this.model);
        }
		

    },

	create: function(operation, callback, scope) {
		var thisProxy = this;
		
		operation.setStarted();
		
		var rc = operation.records[0].data;
		
		var newId = rc.id;
		
		// New item in an existing list
		if (typeof newId != 'undefined' && newId.length > 0) {
		
		} // New list
		else { 
			var list_create_query = 'insert into check_list (id, listName, listType) values (?, ?, ?)';
			
			newId = makeid();
			var lname = rc.listName;
			var ltype = rc.listType;
			
			this.db.transaction(
				function(transaction) {
					transaction.executeSql(list_create_query, [newId, lname, ltype],
					function() {
						operation.setCompleted();
						operation.setSuccessful();
						
						if (typeof callback == 'function') {
							callback.call(scope || thisProxy, operation);
						}
					},
					errorHandler);
				}
			);
				
			
		}
	},
	
	read: function(operation, callback, scope) {
		
		var thisProxy = this;
		
						
		this.db.transaction(
			function (transaction) {
			
				var lst_slct_query = 'select li.id as itemId, li.itemOrder, li.item, li.status as itemStatus, cl.id as listId, cl.listName, cl.listType, cl.status as listStatus, cl.createDate from check_list cl left outer join list_items li on cl.id = li.listId order by cl.id, li.status, li.itemOrder';

								
				transaction.executeSql(lst_slct_query, [], function(transaction, results) {
					
					var localLists = loadAllRecords(transaction, results);
					
					operation.resultSet = new Ext.data.ResultSet({
						records: localLists,
						total: localLists.length,
						loaded: true
					});	
					
					operation.setSuccessful();
					operation.setCompleted();
					
					if (typeof callback == 'function') {
						callback.call(scope || thisProxy, operation);
					}
																				 					
				}, errorHandler);
			}
		);

	},
	
	update: function(operation, callback, scope) {
		
		var action = operation.action;
		
		console.log('Proxy update is called. ' + action);
		
		var thisProxy = this;
		
		operation.setStarted();
		
		// Add a new item to the list
		if (action == 'createNewItem') {
			// console.log('passing params length: ' + operation.records.length);
		
			var params = operation.records[0];
			
			var liId = params.liId;
			var item = params.item;
			
			var get_max_item_order = 'select COALESCE(max(itemOrder), 0)as maxOrder from list_items where listId = ?';
			var item_create_query = 'insert into list_items (listId, item, itemOrder) values (?, ?, ?)';
									
			this.db.transaction(
				function(transaction) {
				
					var curOrder = 0;
					
					transaction.executeSql(get_max_item_order, [liId], function(transaction, results){
						// console.log('list id is ' + liId);
						if (results != null && results.rows != null && results.rows.length > 0) {
							
							var maxOrder = results.rows.item(0).maxOrder;
							// console.log('max order is ' + maxOrder);
							curOrder = maxOrder + 1;
							
							// console.log('current order is ' + curOrder);
					
						transaction.executeSql(item_create_query, [liId, item, curOrder], function() {
							operation.setCompleted();
							operation.setSuccessful();
						
							if (typeof callback == 'function') {
								callback.call(scope || thisProxy, operation);
							}
						},
						errorHandler);
						}
					}, errorHandler);
					
					
				}
			);
		 }
		 else if (action == 'updateListName') {
			var rcd = operation.records[0];
			
			var liId = rcd.get('id');
			var liName = rcd.get('listName');
			
			// console.log('Update list ' + liId + ' with list name ' + liName);
			
			var update_list_name = 'update check_list set listName = ? where id = ?';
			
			this.db.transaction(
				function(transaction) {
				
					transaction.executeSql(update_list_name, [liName, liId], function() {
							operation.setCompleted();
							operation.setSuccessful();
						
							if (typeof callback == 'function') {
								// console.log('before call back');
								
								callback.call(scope || thisProxy, rcd);
							}
						},
						errorHandler);
				}
			);
			
		 } 
		 else if (action == 'removeSingleItem') {
			var params = operation.records[0];
			
			var liId = params.liId;
			var itOrder = params.itemId;
			
			var rmv_single_item_query = 'delete from list_items where listId = ? and itemOrder = ?';
			
			this.db.transaction(
				function(transaction) {
				
					transaction.executeSql(rmv_single_item_query, [liId, itOrder], function() {
							operation.setCompleted();
							operation.setSuccessful();
						
							if (typeof callback == 'function') {
								callback.call(scope || thisProxy, operation);
							}
						},
						errorHandler);
				}
			);
		 }
		 else if (action == 'updateItemValue') {
			var params = operation.records[0];
			
			var liId = params.liId;
			var itOrder = params.itemId;
			var itemVal = params.item;
			
			var update_item_val_query = 'update list_items set item = ? where listId = ? and itemOrder = ?';
			var lst_slct_query = 'select li.id as itemId, li.itemOrder, li.item, li.status as itemStatus, cl.id as listId, cl.listName, cl.listType, cl.status as listStatus, cl.createDate from check_list cl left outer join list_items li on cl.id = li.listId order by cl.id, li.status, li.itemOrder';
			
			console.log('passed list_id: ' + liId + ' item_order: ' + itOrder + ' item_val: ' + itemVal);
			
			this.db.transaction(
				function(transaction) {
				
					transaction.executeSql(update_item_val_query, [itemVal, liId, itOrder], function() {
							
							//console.log('bp 2');
							
							transaction.executeSql(lst_slct_query, [], function(transaction, results) {
									
									//console.log('bp 3');
									
									var localLists = loadAllRecords(transaction, results);
								
									// console.log('Updated store loaded.');
									
									var rcd;
									
									for (var j = 0; j < localLists.length; j++) {
										rcd = localLists[j];
										if (rcd.get('id') == liId) {
											console.log('Correct record load. id: ' + rcd.get('id'));
											break;
										}
									}
																											
									operation.setCompleted();
									operation.setSuccessful();
						
									if (typeof callback == 'function') {
										callback.call(scope || thisProxy, rcd, itemVal);
									}
							},	errorHandler);
						
					}, errorHandler);
				}
			);

		 }
		 else {
			var params = operation.records[0];
			
			var liId = params.liId;
			var itOrder = params.itemOrder;
			var itStatus = params.status;
			
			// console.log('liId/itOrder/itStatus: ' + liId + '/' + itOrder + '/' + itStatus);
			
			var update_list_query = 'update list_items set status = ? where listId = ? and itemOrder = ?';
			
			this.db.transaction(
				function(transaction) {
				
					transaction.executeSql(update_list_query, [itStatus, liId, itOrder], function() {
							operation.setCompleted();
							operation.setSuccessful();
						
							if (typeof callback == 'function') {
								callback.call(scope || thisProxy, operation);
							}
						},
						errorHandler);
				}
			);
		 }
		
		
	},
	
	destroy: function(operation, callback, scope) {
		
		console.log('Proxy destroy is called');
		
		var thisProxy = this;
		
		operation.setStarted();
		
		var rc = operation.records[0].data;
		
		var liId = rc.id;
		
		
		var clear_list_query = 'delete from list_items where listId = ?';
		var remove_list_query = 'delete from check_list where id = ?';
		
		this.db.transaction(
			function(transaction) {
				transaction.executeSql(clear_list_query, [liId], function(){}, errorHandler);
				
				transaction.executeSql(remove_list_query, [liId],
					function() {
						operation.setCompleted();
						operation.setSuccessful();
						
						if (typeof callback == 'function') {
							callback.call(scope || thisProxy, operation);
						}
					}, errorHandler);
			}
		);
	}
	
	
}));

function errorHandler(transaction, error){
	console.log('Failed to load records. ' + error.message + ' code: ' + error.code);
}

function loadAllRecords(transaction, results) {
	var localLists = [];
					
	if (results != null && results.rows != null && results.rows.length > 0) {
		var len = results.rows.length;
		
		// console.log('results number: ' + len);
		
		var curLiId = '';
		var theList;
		var listItems = [];
						
		var checked = 0;

		for (var i = 0; i < len; i++) {
			var id = results.rows.item(i).listId;
								
			if (id != curLiId) {
				if (i > 0) {
					theList.set('total', listItems.length);
					theList.set('checked', checked);
					theList.set('items', listItems);
					localLists.push(theList); 
					checked = 0;
				}
				
				curLiId = id;
				theList = Ext.ModelMgr.create({
					id: curLiId,
					listName: results.rows.item(i).listName,
					listType: results.rows.item(i).listType,
					createDate: results.rows.item(i).createDate,
					status: results.rows.item(i).status
				}, 'app.models.CheckList');
				
				listItems = [];
								
								
				// console.log('list name: ' + theList.get('listName'));
			}
								
							
			if (results.rows.item(i).itemId) {
				var liItem = Ext.ModelMgr.create({
					listId: curLiId,
					itemOrder: results.rows.item(i).itemOrder,
					item: results.rows.item(i).item,
					status: results.rows.item(i).itemStatus
				}, 'app.models.ListItem');
							
				if (results.rows.item(i).itemStatus == 'checked') {
					checked++;
				}
												
				listItems.push(liItem);
			}
								
		}
						
		theList.set('total', listItems.length);
		theList.set('checked', checked);
		theList.set('items', listItems);	
		localLists.push(theList);
												
	}
	
	return localLists;
}

function makeid()
{
    var text = '';
    var possible = 'abcdefghijklmnopqrstuvwxyz0123456789';

    for( var i=0; i < 8; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}



